﻿#include "PLCWriteThread.h"


//静态成员初始化（设备ID列表，仅cpp可见）


const QStringList s_valveID_ReadAndWrite = {
    u8"omron.nj101.氮气阀上位机", u8"omron.nj101.硫化氢1_32阀上位机",
    u8"omron.nj101.硫化氢1_52阀上位机", u8"omron.nj101.硫化氢2_32阀上位机",
    u8"omron.nj101.硫化氢2_52阀上位机", u8"omron.nj101.源瓶1line阀上位机",
    u8"omron.nj101.源瓶1Run阀上位机", u8"omron.nj101.源瓶2Line阀上位机",
    u8"omron.nj101.源瓶2Run阀上位机", u8"omron.nj101.换源气阀上位机"
};



const QStringList s_flowmeterID_ReadAndWrite = {
    u8"omron.nj101.流量1设定", u8"omron.nj101.流量2设定", u8"omron.nj101.流量3设定",
    u8"omron.nj101.流量4设定", u8"omron.nj101.流量5设定", u8"omron.nj101.流量6设定",
    u8"omron.nj101.流量7设定", u8"omron.nj101.流量8设定", u8"omron.nj101.流量9设定"
};



const QStringList s_pressuremeterID_ReadAndWrite = {
    u8"omron.nj101.压力设定1", u8"omron.nj101.压力设定2"
};



const QStringList s_MKSID_ReadAndWrite = {
    u8"omron.nj101.MKS设定1", u8"omron.nj101.MKS设定2", u8"omron.nj101.MKS控制"
};



const QStringList s_temperatureID_ReadAndWrite = {
    u8"omron.nj101.温控启动", u8"omron.nj101.上位机温控启动", u8"omron.nj101.温度设定值动态", u8"omron.nj101.温度设定值动态1"
};



PLCWriteThread::PLCWriteThread(Open62541 *client, PLCCommOPCUA *parent)
    :m_pParent{parent},
    m_client(client)
{


}

void PLCWriteThread::stop()
{
    m_isRuning = false;
    m_sem.release();
}

void PLCWriteThread::writeValveStatus(int valveChannel, bool status)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteValveStatus;
    task.channel = valveChannel;
    task.boolValue = status;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeAllValveStatus(const QVector<bool> &status)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteAllValveStatus;
    task.boolVector = status;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeFlowRate(int flowmeterChannel, int16_t inputValue)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteFlowRate;
    task.channel = flowmeterChannel;
    task.int16Value = inputValue;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeAllFlowRate(const QVector<int16_t> &inputValue)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteAllFlowRate;
    task.int16Vector = inputValue;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writePressure(int pressuremeterChannel, int16_t inputValue)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WritePressure;
    task.channel = pressuremeterChannel;
    task.int16Value = inputValue;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeAllPressure(const QVector<int16_t> &inputValue)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteAllPressure;
    task.int16Vector = inputValue;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeMKS(int16_t pressure, int16_t openingAmplitude, int16_t switchMode)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteMKS;
    task.mksPressure = pressure;
    task.mksOpening = openingAmplitude;
    task.mksMode = switchMode;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::writeTemperature(bool status1, bool status2, int16_t temperature1, int16_t temperature2)
{
    QMutexLocker locker(&m_mutex_tasks);
    Task task;
    task.type = Task::WriteTemperature;
    task.tempStatus1 = status1;
    task.tempStatus2 = status2;
    task.temp1 = temperature1;
    task.temp2 = temperature2;
    m_tasks.enqueue(task);

    m_sem.release(1);
}

void PLCWriteThread::run()
{
    bool success = false;
    int count = 0;
    m_isRuning = true;

    while(m_isRuning)
    {
        m_sem.acquire();
        if(m_tasks.empty() || !m_isRuning) return; // 这时说明我们要结束这个线程。在软件要退出时我们会故意让这种情况发生
        Task task = m_tasks.dequeue();

        switch (task.type) {
        case Task::WriteValveStatus:
            //写单个电磁阀值
            if (task.channel > 0 && task.channel <= s_valveID_ReadAndWrite.size()) {
                success = m_client->Open62541_WriteData(2, s_valveID_ReadAndWrite[task.channel - 1], task.boolValue);
            }
            //emit signals_valveStatusWritten(task.channel, success);
            break;

        case Task::WriteFlowRate:
            //写单个流量计
            if (task.channel > 0 && task.channel <= s_flowmeterID_ReadAndWrite.size())
            {
                success = m_client->Open62541_WriteData(2, s_flowmeterID_ReadAndWrite[task.channel - 1], task.int16Value);
            }
            break;

        case Task::WriteMKS:
            //写mks
            if (s_MKSID_ReadAndWrite.size() >= 3)
            {
                success = m_client->Open62541_WriteData(2, s_MKSID_ReadAndWrite[0], task.mksPressure) &&
                          m_client->Open62541_WriteData(2, s_MKSID_ReadAndWrite[1], task.mksOpening) &&
                          m_client->Open62541_WriteData(2, s_MKSID_ReadAndWrite[2], task.mksMode);
            }
            break;

        case Task::WritePressure:
            //写单个压力值
            if (task.channel > 0 && task.channel <= s_pressuremeterID_ReadAndWrite.size())
            {
                success = m_client->Open62541_WriteData(2, s_pressuremeterID_ReadAndWrite[task.channel - 1], task.int16Value);
            }
            break;

        case Task::WriteTemperature:
            //写温度
            if (s_temperatureID_ReadAndWrite.size() >= 3)
            {
                success = m_client->Open62541_WriteData(2, s_temperatureID_ReadAndWrite[0], task.tempStatus1) &&
                          m_client->Open62541_WriteData(2, s_temperatureID_ReadAndWrite[1], task.tempStatus2) &&
                          m_client->Open62541_WriteData(2, s_temperatureID_ReadAndWrite[2], task.temp1) &&
                          m_client->Open62541_WriteData(2, s_temperatureID_ReadAndWrite[3], task.temp2);
            }
            break;

        case Task::WriteAllFlowRate:
            //写所有流量计
            count = qMin(task.int16Vector.size(), s_flowmeterID_ReadAndWrite.size());
            for (int i = 0; i < count; ++i)
            {
                if (!m_client->Open62541_WriteData(2, s_flowmeterID_ReadAndWrite[i], task.int16Vector[i]))
                {
                    success = false;
                    break;
                }
            }
            break;

        case Task::WriteAllPressure:
            count = qMin(task.int16Vector.size(), s_pressuremeterID_ReadAndWrite.size());
            for (int i = 0; i < count; ++i)
            {
                if (!m_client->Open62541_WriteData(2, s_pressuremeterID_ReadAndWrite[i], task.int16Vector[i]))
                {
                    success = false;
                    break;
                }
            }
            break;

        case Task::WriteAllValveStatus:
            //写所有电磁阀值
            count = qMin(task.boolVector.size(), s_valveID_ReadAndWrite.size());
            for (int i = 0; i < count; ++i)
            {
                if (!m_client->Open62541_WriteData(2, s_valveID_ReadAndWrite[i], task.boolVector[i]))
                {
                    success = false;
                    break;
                }
            }
            break;
        default:
            break;
        }
    }
}
